package com.logic.landseaserver.common.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.logic.landseaserver.domain.ReportData;

public class FopReport {
	private static Logger logger = LoggerFactory.getLogger(FopReport.class);
	// Step 1: Construct a FopFactory
	private static final FopFactory fopFactory = FopFactory.newInstance();

	/**
	 * 根据xsl模板及xml数据文件生成pdf
	 */
	public static ReportData createReport(String xsltFile, String xmlFile, String fopConfigPath) throws Exception {

		ReportData reportData = new ReportData();
		reportData.setContentType("application/pdf");
		logger.info("*************************设置基路径**************************");
		fopFactory.setUserConfig(fopConfigPath + "/conf/fop.xml");
		fopFactory.setBaseURL(fopConfigPath + "/report/images");
		logger.info(fopFactory.getBaseURL());
		fopFactory.getFontManager().setFontBaseURL(fopConfigPath + "/conf/fonts");
		logger.info(fopFactory.getFontManager().getFontBaseURL());
		// Step 2: Set up output stream.
		ByteArrayOutputStream out = new ByteArrayOutputStream();

		try {
			// Step 3: Construct fop with desired output format
			Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);

			// Step 4: Setup XSLT using identity transformer
			TransformerFactory factory = TransformerFactory.newInstance();
			Transformer transformer = factory.newTransformer(new StreamSource(new File(xsltFile)));

			// Step 5: Setup input and output for XSLT transformation
			Source src = new StreamSource(new File(xmlFile));
			// Source src = new StreamSource(new StringReader(myString));

			// Step 6: Resulting SAX events (the generated FO) must be piped
			// through to FOP
			Result res = new SAXResult(fop.getDefaultHandler());

			// Step 7: Start XSLT transformation and FOP processing
			transformer.transform(src, res);

			reportData.setData(out.toByteArray());
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			throw e;
		} finally {
			out.close();
			logger.info("===============Finally for second createReport.");
		}
		return reportData;
	}

	/**
	 * 根据xsl模板及xml字节数组生成pdf
	 */
	public static ReportData createReport(String xsltFile, byte[] bXmlData, String fopConfigPath) throws Exception {

		ReportData reportData = new ReportData();
		try {
			// convert xml bytes to a temp file
			File xmlFile = File.createTempFile("FOP", ".tmp");
			FileOutputStream fos = new FileOutputStream(xmlFile);
			fos.write(bXmlData);
			fos.close();

			reportData = createReport(xsltFile, xmlFile.getAbsolutePath(), fopConfigPath);
			// delete temp file
			xmlFile.delete();
		} catch (Exception e) {
			logger.error(e.getMessage());
			throw e;
		} finally {
			logger.info("===============Finally for first createReport.");
		}
		return reportData;
	}
}
